let http = require("http");
let request = require("./request");
let response = require("./response");
let context = require("./context");
class Application {
  constructor() {
    this.middleware = [];
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }
  //   监听系统端口
  listen(...args) {
    let server = http.createServer(this.callback());
    server.listen(...args);
  }
  use(fn) {
    this.middleware.push(fn);
  }
  callback() {
    const handle_request = (req, res) => {
      let ctx = this.createContext(req, res);
      //   this.middleware.map((fn, next) => {
      //     fn(ctx, next);
      //   });
      this.compose()(ctx);
    };
    return handle_request;
  }

  createContext(req, res) {
    let context = Object.create(this.context);
    const request = (context.request = Object.create(this.request));
    const response = (context.response = Object.create(this.response));
    request.response = response;
    response.request = request;
    context.request.req = req;
    context.response.req = req;
    context.request.res = res;
    context.response.res = res;
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    return context;
  }

  compose() {
    return async ctx => {
      let length = this.middleware.length;

      let createNext = (middleware, oldNext) => {
        return async () => {
          await middleware(ctx, oldNext);
        };
      };
      let next = async () => {
        return Promise.resolve();
      };
      for (var i = length; i >= 0; i--) {
        let currentMiddleware = this.middleware[i];
        next = createNext(currentMiddleware, next);
      }
      await next();
    };
  }
}

module.exports = Application;
